package com.gutai.admin.service.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.stereotype.Service;

import com.gutai.admin.common.entity.dto.CategoryLevelDto;
import com.gutai.admin.common.entity.dto.LevelDto;
import com.gutai.admin.dao.ICategoryDao;
import com.gutai.admin.entity.Category;
import com.gutai.admin.service.ICategoryService;

/**
 * 
 * 描述：
 * 
 * <pre>
 * HISTORY
 * ****************************************************************************
 *  ID    DATE            PERSON            REASON
 *  1     2018年11月7日         YC           Create
 * ****************************************************************************
 * </pre>
 * 
 * @author YC
 * @version 1.0
 */
@Service
@CacheConfig(cacheNames = "category")
public class CategoryService implements ICategoryService {

    @Autowired
    private ICategoryDao categoryDao;
    @Autowired
    private ICategoryService categoryService; // 注入自己，触发缓存使用

    @Override
    public List<Category> getList(String name) {
//        return categoryDao.findByName(name);
        return categoryService.getAll().stream()
                .filter(category -> category.getName().indexOf(name) >= 0)
                .collect(Collectors.toList());
    }

    @Override
    @Cacheable(unless = "#result == null || #result.size()==0")
    public List<Category> getAll() {
        Sort sort = new Sort(Direction.DESC, "createTime");
        return categoryDao.findAll(sort);
    }

    @Override
    @CacheEvict(allEntries = true)
    public void add(Category entity) {
        if (entity.getParentId() != null && entity.getParentId() != 0) {
            entity.setLevel("L2");
        } else {
            entity.setLevel("L1");
        }
        categoryDao.saveAndFlush(entity);
    }

    @Override
    @CacheEvict(allEntries = true)
    public void update(Category entity) {
        categoryDao.saveAndFlush(entity);
    }

    @Override
    @CacheEvict(allEntries = true)
    public void delete(int id) {
        categoryDao.deleteById(id);
    }

    @Override
    public List<CategoryLevelDto> getRelationCategory() {
        List<CategoryLevelDto> categoryLevelList = new ArrayList<>();
        Map<Integer, List<Category>> subCategoryRelation = categoryService.getAll().stream()
                .collect(Collectors.groupingBy(Category::getParentId));
        List<Category> rootCategorys= subCategoryRelation.get(0);// L1
        for (Category category: rootCategorys){
            CategoryLevelDto level = createCategoryLevel(category, 0);
            categoryLevelList.add(level);
        }
        List<Integer> parentCategoryIds = new ArrayList<>(); // 待处理的父类类别
        for (Integer parentId : subCategoryRelation.keySet()){
            if (parentId != 0) {
                parentCategoryIds.add(parentId);
            }
        }
        int index =0;
        while (!parentCategoryIds.isEmpty()) {
            Integer parentId = parentCategoryIds.get(index);
            CategoryLevelDto partentCategory = getCategoryById(categoryLevelList, parentId);
            if (partentCategory == null) {
                index++;
                continue;
            }
            partentCategory.setSubCategorylist(new ArrayList<>());
            List<Category> categorys= subCategoryRelation.get(parentId);
            for (Category category : categorys) {
                CategoryLevelDto level = createCategoryLevel(category, parentId);
                partentCategory.getSubCategorylist().add(level);
            }
            parentCategoryIds.remove(index);
            index =0;
        }
        return categoryLevelList;
    }

    /**
     * 转换DTO实体
     * @param category
     * @param parentId
     * @return
     */
    private CategoryLevelDto createCategoryLevel(Category category, Integer parentId){
        CategoryLevelDto level = new CategoryLevelDto();
        level.setCategoryId(category.getId());
        level.setCategoryName(category.getName());
        level.setLevel(category.getLevel());
        level.setParentId(parentId);
        // level.setSubCategorylist(new ArrayList<>());
        return level;
    }
    /**
     * 根据ID获取类别对象，如果不存在则新建一个对象
     * @param categoryLevelList
     * @param id
     * @return
     */
    private CategoryLevelDto getCategoryById(List<CategoryLevelDto> categoryLevelList, Integer id) {
        if (!categoryLevelList.isEmpty()){
            return categoryLevelList.stream()
                    .filter(categoryLevel -> id.equals(categoryLevel.getCategoryId()))
                    .findFirst().orElse(null);
        }
        return null;
    }
//  @Override
//  public Map<String, CategoryLevelDto> getRelationShip(){
//      List<Category>  list = categoryDao.queryList();
//      Collections.sort(list, new Comparator<Category>() {
//          public int compare(Category ca1, Category ca2) {
//              return ca1.getLevel().compareTo(ca2.getLevel());
//          }
//      });
//      Map<String, CategoryLevelDto> listDto = new HashMap<>();
//      for (Category category : list) {
//          if(category.getLevel()=="L1") {
//
//          }
//      }
//      return null;
//  }
//    private void sortLeval(Map<String, CategoryLevelDto> result, List<Category> list) {
//        for (Category category : list) {
//            if (result.containsKey(category.getParentId())) {
//                CategoryLevelDto tmp = result.get(category.getParentId().toString());
//                tmp.getSubCategorylist()
//            }
//        }
//    }
    @Override
    public Category findById(int id) {
        return categoryDao.findById(id);
    }
    
    @Override
    public List<Category> findAllParent() {
        return categoryService.getAll().stream()
                .filter(category -> "L1".equals(category.getLevel())).collect(Collectors.toList());
    }
    
    @Override
    public List<LevelDto> findAllLevel() {
        List<String> levelNames = categoryService.getAll().stream().map(Category::getLevel)
                .distinct().collect(Collectors.toList()); // 获取当前类别的所有级别
        return levelNames.stream().map(levelName->new LevelDto(levelName,levelName+"级别")).collect(Collectors.toList());
    }
}
